import os
import subprocess
from django.http import HttpResponse
from django.shortcuts import render, redirect
import pymysql
from AppManager import Crontab as AM_Crontab
from AppManager.Crontab import newCronDict, gethostlist
from OpManager import settings
from AppManager.tools.tools import unique
from HostManager import SSH
from AppManager import Firewall
from AppManager import Ansible


@settings.auth(AuthType="AppManager", AuthNum=1)
def Webssh(requests):
    return render(requests, "Webssh.html")


@settings.auth(AuthType="AppManager", AuthNum=1)
def FullScreenSsh(requests):
    return render(requests, "FullScreenSsh.html")


def upload_ssh_key(request):
    if request.method == 'POST':
        pkey = request.FILES.get('pkey')
        ssh_key = pkey.read().decode('utf-8')

        while True:
            filename = unique()
            ssh_key_path = os.path.join(settings.TMP_DIR, filename)
            if not os.path.isfile(ssh_key_path):
                with open(ssh_key_path, 'w') as f:
                    f.write(ssh_key)
                break
            else:
                continue

        return HttpResponse(filename)


@settings.auth(AuthType="AppManager", AuthNum=3)
def WebMysql(requests):
    context = {
        "hosts": gethostlist()
    }
    return render(requests, "WebMysql.html", context)


# 通用资产Mysql管理
@settings.auth(AuthType="AppManager", AuthNum=3)
def WebMysql_Ip(requests):
    if requests.method == 'GET':
        return redirect("/mysql")
    MysqData = {
        "ip": requests.POST["ip"],
        "user": requests.POST["user"],
        "password": requests.POST["password"],
        "database": requests.POST["database"],
        "port": requests.POST["port"]
    }
    resDict = RemoteMysql(MysqData, requests.POST["sql"], requests.POST["type"])
    return render(requests, "WebMysql.html", getcontext(resDict))


# 已有记录的资产Mysql管理
@settings.auth(AuthType="AppManager", AuthNum=3)
def WebMysql_Host(requests):
    if requests.method == 'GET':
        return redirect("/mysql")
    MysqData = {
        "ip": AM_Crontab.hostdict[requests.POST["hostname"]]["ip"],
        "user": requests.POST["user"],
        "password": requests.POST["password"],
        "database": requests.POST["database"],
        "port": requests.POST["port"]
    }
    resDict = RemoteMysql(MysqData, requests.POST["sql"], requests.POST["type"])
    return render(requests, "WebMysql.html", getcontext(resDict))


# 代码复用，烦死了 * 2
def getcontext(resDict):
    message = ""
    restitle = []
    reslist = ()
    if resDict["type"] == "msg":
        message = resDict["res"]
    elif resDict["type"] == "list":
        restitle = resDict["title"]
        reslist = resDict["res"]
    context = {
        "hosts": AM_Crontab.hostdict,
        "message": message,
        "restitle": restitle,
        "reslist": reslist
    }
    return context


# web端发送sql语句的执行
def RemoteMysql(MysqlData: dict, sql: str, sqltype: int):
    resDict = {
        "type": "msg",
        "res": "",
        "title": []
    }
    # 读取数据库信息进行验证
    try:
        tmpconn = pymysql.connect(MysqlData['ip'], MysqlData['user'], MysqlData['password'], MysqlData['database'],
                                  int(MysqlData["port"]))
        tmpcursor = tmpconn.cursor()
        try:
            # 执行sql
            tmpcursor.execute(sql)
            # 获取单条数据
            if sqltype == "1":
                # 为了让前端统一处理单元组和多元组，都变成多元组
                result = (tmpcursor.fetchone(),)
                resDict["type"] = "list"
                for titlelist in tmpcursor.description:
                    resDict["title"].append(titlelist[0])
            # 获取所有数据
            elif sqltype == "99":
                result = tmpcursor.fetchall()
                resDict["type"] = "list"
                for titlelist in tmpcursor.description:
                    resDict["title"].append(titlelist[0])
            elif sqltype == "0":
                tmpconn.commit()
                result = "执行完成"
            else:
                result = "模式不正确"
        except Exception as e:
            result = "执行失败：" + str(type(e)) + ":" + str(e)
            tmpconn.rollback()
        tmpconn.close()
    except Exception as e:
        print(e)
        result = "连接失败：" + str(type(e)) + ":" + str(e)
    resDict["res"] = result
    return resDict


# web端查看定时调度
@settings.auth(AuthType="AppManager", AuthNum=4)
def Crontab(requests):
    if requests.method == 'GET':
        context = {
            "cronsDict": AM_Crontab.CronDict
        }
        return render(requests, "Crontab.html", context)


# web端刷新定时调度
@settings.auth(AuthType="AppManager", AuthNum=4)
def RefreshCron(requests):
    newCronDict()
    return redirect("/crontab")


@settings.auth(AuthType="AppManager", AuthNum=4)
def CronDel(requests):
    if requests.method == 'POST':
        hostname = requests.POST["hostname"]
        tmp = "sed -i \'%sd\' /var/spool/cron/%s" % (requests.POST["id"], requests.POST["username"])
        command = (tmp,)
        if hostname == "Op主机":
            p = subprocess.Popen(tmp, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
            print(p.stderr)
        else:
            res = SSH.SshComm(AM_Crontab.hostdict[hostname]["ip"], AM_Crontab.hostdict[hostname]["port"],
                              AM_Crontab.hostdict[hostname]["user"],
                              AM_Crontab.hostdict[hostname]["password"], command)
            print(res[tmp]["stderr"])
    newCronDict()
    return redirect("/crontab")


@settings.auth(AuthType="AppManager", AuthNum=4)
def CronAdd(requests):
    if requests.method == 'POST':
        tmp = "echo \'%s\' >> /var/spool/cron/%s" % (requests.POST["context"], requests.POST["username"])
        command = (tmp,)
        hostname = requests.POST["hostname"]
        if hostname == "Op主机":
            p = subprocess.Popen(tmp, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
            print(p.stderr)
        else:
            res = SSH.SshComm(AM_Crontab.hostdict[hostname]["ip"], AM_Crontab.hostdict[hostname]["port"],
                              AM_Crontab.hostdict[hostname]["user"],
                              AM_Crontab.hostdict[hostname]["password"], command)
            print(res[tmp]["stderr"])
    newCronDict()
    return redirect("/crontab")


@settings.auth(AuthType="AppManager", AuthNum=4)
def CronEdit(requests):
    if requests.method == 'POST':
        hostname = requests.POST["hostname"]
        tmp1 = "sed -i \'%sd\' /var/spool/cron/%s" % (requests.POST["id"], requests.POST["username"])
        tmp2 = "echo \'%s\' >> /var/spool/cron/%s" % (requests.POST["context"], requests.POST["username"])
        command = (tmp1, tmp2)
        if hostname == "Op主机":
            p1 = subprocess.Popen(tmp1, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
            p2 = subprocess.Popen(tmp2, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
            print(p1.stderr)
            print(p2.stderr)
        else:
            res = SSH.SshComm(AM_Crontab.hostdict[hostname]["ip"], AM_Crontab.hostdict[hostname]["port"],
                              AM_Crontab.hostdict[hostname]["user"],
                              AM_Crontab.hostdict[hostname]["password"], command)
            print(res[tmp1]["stderr"])
            print(res[tmp2]["stderr"])
    newCronDict()
    return redirect("/crontab")


# 防火墙
@settings.auth(AuthType="AppManager", AuthNum=5)
def FireWall(requests):
    context = {
        "firewalls": Firewall.FireWallDict
    }
    return render(requests, "Firewall.html", context)


# 新增防火墙规则
@settings.auth(AuthType="AppManager", AuthNum=5)
def FWAdd(requests):
    Rules = {
        "port": requests.POST["port"],
        "protocol": requests.POST["protocol"],
        "type": requests.POST["type"],
        "params": requests.POST["params"]
    }
    message = Firewall.EditFWRule(requests.POST["hostname"], Rules, "add")
    context = {
        "firewalls": Firewall.FireWallDict,
        "message": message
    }
    return render(requests, "Firewall.html", context)


# 删除防火墙规则
@settings.auth(AuthType="AppManager", AuthNum=5)
def FWDel(requests):
    message = Firewall.EditFWRule(requests.POST["hostname"], requests.POST["id"], "del")
    context = {
        "firewalls": Firewall.FireWallDict,
        "message": message
    }
    return render(requests, "Firewall.html", context)


# 刷新防火墙规则
@settings.auth(AuthType="AppManager", AuthNum=5)
def refreshFW(requests):
    Firewall.getSelfFireWallDict()
    Firewall.getAllFireWallDict()
    return redirect("/firewall")


# Ansible 管理主界面
@settings.auth(AuthType="AppManager", AuthNum=2)
def ansible(requests):
    return render(requests, "Ansible.html")
